package com.example.drools.service;

import com.example.drools.model.*;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 定价服务类
 */
@Service
public class PricingService {

    @Autowired
    private KieContainer kieContainer;

    /**
     * 执行定价计算
     */
    public List<PriceAdjustment> calculatePricing(UserProfile userProfile, Context context, List<Score> scores) {
        KieSession kieSession = kieContainer.newKieSession();
        List<PriceAdjustment> priceAdjustments = new ArrayList<>();

        try {
            // 设置焦点到定价规则组
            kieSession.getAgenda().getAgendaGroup("pricing").setFocus();

            // 插入事实
            kieSession.insert(userProfile);
            kieSession.insert(context);
            
            // 插入所有分数
            for (Score score : scores) {
                kieSession.insert(score);
            }

            // 触发规则
            kieSession.fireAllRules();

            // 收集定价调整结果
            kieSession.getObjects(object -> object instanceof PriceAdjustment)
                    .forEach(obj -> priceAdjustments.add((PriceAdjustment) obj));

        } finally {
            kieSession.dispose();
        }

        return priceAdjustments;
    }

    /**
     * 简化的定价计算方法
     */
    public PriceAdjustment quickCalculate(String userId, String userType, double originalPrice, int orderQuantity) {
        UserProfile userProfile = new UserProfile();
        userProfile.setId(userId);
        userProfile.setSegments(Set.of(userType));
        userProfile.setRegion("一线城市");

        Context context = new Context();
        context.setPage("商品页面");

        List<Score> scores = List.of(
                new Score(userId, "loyaltyScore", 85.0),
                new Score(userId, "orderCount", 5),
                new Score(userId, "orderQuantity", orderQuantity),
                new Score(userId, "engagement", 70.0)
        );

        List<PriceAdjustment> adjustments = calculatePricing(userProfile, context, scores);
        
        // 返回最优惠的价格调整（最小的multiplier）
        return adjustments.stream()
                .min((a1, a2) -> Double.compare(a1.getMultiplier(), a2.getMultiplier()))
                .orElse(new PriceAdjustment(userId, "DEFAULT_PRICE", 1.0, "标准价格"));
    }

    /**
     * 计算最终价格
     */
    public double calculateFinalPrice(String userId, String userType, double originalPrice, int orderQuantity) {
        PriceAdjustment adjustment = quickCalculate(userId, userType, originalPrice, orderQuantity);
        return adjustment.calculateAdjustedPrice(originalPrice);
    }

    /**
     * 批量定价计算
     */
    public List<PriceAdjustment> batchCalculate(List<UserProfile> userProfiles, Context context, double basePrice) {
        List<PriceAdjustment> allAdjustments = new ArrayList<>();
        
        for (UserProfile userProfile : userProfiles) {
            // 为每个用户生成模拟分数
            List<Score> scores = generateMockScores(userProfile.getId());
            List<PriceAdjustment> userAdjustments = calculatePricing(userProfile, context, scores);
            allAdjustments.addAll(userAdjustments);
        }
        
        return allAdjustments;
    }

    /**
     * 获取用户的所有可用折扣
     */
    public List<PriceAdjustment> getAvailableDiscounts(UserProfile userProfile, Context context) {
        List<Score> scores = generateMockScores(userProfile.getId());
        List<PriceAdjustment> adjustments = calculatePricing(userProfile, context, scores);
        
        // 只返回折扣（multiplier < 1.0）
        return adjustments.stream()
                .filter(adj -> adj.getMultiplier() < 1.0)
                .toList();
    }

    /**
     * 生成模拟分数数据
     */
    private List<Score> generateMockScores(String userId) {
        return List.of(
                new Score(userId, "loyaltyScore", Math.random() * 100),
                new Score(userId, "orderCount", (int)(Math.random() * 20)),
                new Score(userId, "orderQuantity", (int)(Math.random() * 50)),
                new Score(userId, "engagement", Math.random() * 100),
                new Score(userId, "daysSinceLastOrder", (int)(Math.random() * 90))
        );
    }
}